 /*******************************************************************************
  * Copyright (c) 2000, 2006 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
  * IBM Corporation - initial API and implementation
  *******************************************************************************/

 package org.eclipse.ui.internal;

 import com.ibm.icu.text.Collator;
 import java.util.ArrayList ;
 import java.util.Arrays ;
 import java.util.Iterator ;
 import java.util.List ;

 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.IMenuListener;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.action.Separator;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.KeyEvent;
 import org.eclipse.swt.events.KeyListener;
 import org.eclipse.swt.events.MouseAdapter;
 import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Table;
 import org.eclipse.swt.widgets.TableItem;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IEditorReference;
 import org.eclipse.ui.IPartListener2;
 import org.eclipse.ui.IPropertyListener;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.IWorkbenchPartReference;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PlatformUI;

 public class EditorList {
     private WorkbenchWindow window;

     private EditorStack workbook;

     private Table editorsTable;

     private static List editorListViews = new ArrayList ();

     private List elements = new ArrayList ();

     private SaveAction saveAction;

     private CloseAction closeAction;

     private SelectionAction selectCleanAction;

     private SelectionAction InvertSelectionAction;

     private SelectionAction selectAllAction;

     private FullNameAction fullNameAction;

     private SortAction nameSortAction;

     private SortAction MRUSortAction;

     private SetScopeAction windowScopeAction;

     private SetScopeAction pageScopeAction;

     private SetScopeAction tabGroupScopeAction;

     private boolean dropDown; // initialized in constructor

     // options same among all instances of editorList
 private static int sortOrder; // initialized in constructor

     private static int listScope; // initialized in constructor

     private static boolean displayFullPath; // initialized in constructor

     private static Collator collator = Collator.getInstance();

     private static final int SELECT_ALL = 0;

     private static final int INVERT_SELECTION = 1;

     private static final int SELECT_CLEAN = 2;

     private static final int NAME_SORT = IPreferenceConstants.EDITORLIST_NAME_SORT;

     private static final int MRU_SORT = IPreferenceConstants.EDITORLIST_MRU_SORT;

     private static final int SET_WINDOW_SCOPE = IPreferenceConstants.EDITORLIST_SET_WINDOW_SCOPE;

     private static final int SET_PAGE_SCOPE = IPreferenceConstants.EDITORLIST_SET_PAGE_SCOPE;

     private static final int SET_TAB_GROUP_SCOPE = IPreferenceConstants.EDITORLIST_SET_TAB_GROUP_SCOPE;

     private static final String editorListData = "editorListData"; //$NON-NLS-1$

     /**
      * Listen for notifications from the editor part that its title has change or
      * it's dirty, and update view
      *
      * @see IPropertyListener
      */
     private IPropertyListener propertyListener = new IPropertyListener() {
         public void propertyChanged(Object source, int property) {
             if (property == IEditorPart.PROP_DIRTY
                     || property == IWorkbenchPart.PROP_TITLE) {
                 if (source instanceof IEditorPart) {
                     EditorSite site = (EditorSite) ((IEditorPart) source)
                             .getEditorSite();
                     IEditorReference ref = (IEditorReference) site.getPartReference();

                     TableItem[] items = editorsTable.getItems();
                     for (int i = 0; i < items.length; i++) {
                         Adapter editor = (Adapter) items[i]
                                 .getData(editorListData);
                         if (editor.editorRef == ref) {
                             updateItem(items[i], editor);
                         }
                     }
                 }
             }
         }
     };

     private IPartListener2 partListener = new IPartListener2() {
         int counter = 0;

         private void updateEditorList(IWorkbenchPartReference ref) {
             if (ref instanceof IEditorReference) {
                 final Display display = window.getShell().getDisplay();
                 final int TIMER_INTERVAL = 100;
                 counter++;
                 display.timerExec(TIMER_INTERVAL, new Runnable () {
                     public void run() {
                         counter--;
                         // When closing the workbench the delay may allow the editorTable
 // to dispose prior to running.
 if ((counter == 0) && (editorsTable != null)) {
                             updateItems();
                             notifyEditorListViews();
                         }
                     }
                 });
             }
         }

         // select in navigator
 public void partBroughtToTop(IWorkbenchPartReference ref) {
             updateEditorList(ref);
         }

         // select tabs, open editor
 public void partActivated(IWorkbenchPartReference ref) {
             updateEditorList(ref);
         }

         // closeAll
 public void partClosed(IWorkbenchPartReference ref) {
             updateEditorList(ref);
         }

         // delete
 public void partDeactivated(IWorkbenchPartReference ref) {
             updateEditorList(ref);
         }

         public void partOpened(IWorkbenchPartReference ref) {
         }

         public void partHidden(IWorkbenchPartReference ref) {
         }

         public void partVisible(IWorkbenchPartReference ref) {
         }

         public void partInputChanged(IWorkbenchPartReference ref) {
         }
     };

     public EditorList(IWorkbenchWindow window, EditorStack workbook) {
         this.window = (WorkbenchWindow) window;
         this.workbook = workbook;

         listScope = WorkbenchPlugin.getDefault().getPreferenceStore().getInt(
                 IPreferenceConstants.EDITORLIST_SELECTION_SCOPE);
         sortOrder = WorkbenchPlugin.getDefault().getPreferenceStore().getInt(
                 IPreferenceConstants.EDITORLIST_SORT_CRITERIA);
         displayFullPath = WorkbenchPlugin.getDefault().getPreferenceStore()
                 .getBoolean(IPreferenceConstants.EDITORLIST_DISPLAY_FULL_NAME);

         // Special handling for scope selection. The concept of tab groups does
 // not make sense in this situation, so over-ride to page scope
 // uses dropDown for this
 //
 // in addition drop down used to indicate if the editorList must also
 // close the viewform etc.
 dropDown = (workbook != null);
         if (!dropDown) {
             // Views need to listen for part activation/deactivation.
 window.getPartService().addPartListener(partListener);

             // When selectionScope (listScope) is changed, or displayFullPath is
 // changed there is no notification to the editorList views that this
 // happened (i.e. if it happens from a different window or from
 // the pullDown). Keep track of the views and update them
 // appropriately.
 editorListViews.add(this);
         }

         saveAction = new SaveAction();
         closeAction = new CloseAction();
         selectCleanAction = new SelectionAction(SELECT_CLEAN);
         InvertSelectionAction = new SelectionAction(INVERT_SELECTION);
         selectAllAction = new SelectionAction(SELECT_ALL);
         fullNameAction = new FullNameAction();
         nameSortAction = new SortAction(NAME_SORT);
         MRUSortAction = new SortAction(MRU_SORT);
         windowScopeAction = new SetScopeAction(SET_WINDOW_SCOPE);
         pageScopeAction = new SetScopeAction(SET_PAGE_SCOPE);
         tabGroupScopeAction = new SetScopeAction(SET_TAB_GROUP_SCOPE);
     }

     /**
      * Create the EditorList table and menu items.
      */
     public Control createControl(Composite parent) {
         editorsTable = new Table(parent, SWT.MULTI | SWT.V_SCROLL
                 | SWT.H_SCROLL);
         updateItems();
         editorsTable.pack();
         editorsTable.setFocus();

         // Create the context menu
 MenuManager menuMgr = new MenuManager("#PopUp"); //$NON-NLS-1$
 menuMgr.setRemoveAllWhenShown(true);
         menuMgr.addMenuListener(new IMenuListener() {
             public void menuAboutToShow(IMenuManager manager) {
                 setCheckedMenuItems();
                 EditorList.this.fillContextMenu(manager);
             }
         });

         editorsTable.setMenu(menuMgr.createContextMenu(editorsTable));
         editorsTable.addKeyListener(new KeyListener() {
             public void keyPressed(KeyEvent e) {
                 if (e.character == SWT.ESC) {
                     destroyControl();
                 }
                 if (e.character == ' ' || e.character == SWT.CR) {
                     handleSelectionEvent(true);
                 }
             }

             public void keyReleased(KeyEvent e) {
             }
         });

         editorsTable.addMouseListener(new MouseAdapter() {
             public void mouseDown(MouseEvent e) {
                 if ((e.stateMask & SWT.CTRL) != 0
                         || (e.stateMask & SWT.SHIFT) != 0) {
                     return;
                 }
                 if (e.button != 3) {
                     handleSelectionEvent(true);
                 }
             }
         });

         return editorsTable;
     }

     public void dispose() {
         editorsTable = null;
         editorListViews.remove(this);

         // remove the listeners
 elements = new ArrayList ();
         getAllEditors(elements);
         for (Iterator iterator = elements.iterator(); iterator.hasNext();) {
             Adapter e = (Adapter) iterator.next();
             e.editorRef.removePropertyListener(propertyListener);
         }
         window.getPartService().removePartListener(partListener);
     }

     public void destroyControl() {
         if (dropDown && (editorsTable != null)) {
             Composite parent = editorsTable.getParent();
             parent.dispose();
             dispose();
         }
     }

     public Control getControl() {
         return editorsTable;
     }

     public int getItemCount() {
         return editorsTable.getItemCount();
     }

     private void notifyEditorListViews() {
         for (Iterator iterator = editorListViews.iterator(); iterator.hasNext();) {
             EditorList editorList = (EditorList) iterator.next();
             if (editorList != this) {
                 editorList.updateItems();
             }
         }
     }

     private void handleSelectionEvent(boolean mouseEvent) {
         TableItem[] selection = editorsTable.getSelection();
         if (selection.length > 0) {
             boolean enableSaveAction = false;
             for (int i = 0; i < selection.length; i++) {
                 Adapter editor = (Adapter) selection[i].getData(editorListData);
                 if (editor.isDirty()) {
                     enableSaveAction = true;
                     break;
                 }
             }
             saveAction.setEnabled(enableSaveAction);
             closeAction.setEnabled(true);
         } else {
             saveAction.setEnabled(false);
             closeAction.setEnabled(false);
         }
         if ((selection.length == 1) && mouseEvent) {
             Adapter a = (Adapter) selection[0].getData(editorListData);
             destroyControl();
             a.activate(dropDown);
         }
         notifyEditorListViews();
     }

     private void setCheckedMenuItems() {
         fullNameAction.setChecked(displayFullPath);
         nameSortAction.setChecked(EditorList.sortOrder == NAME_SORT);
         MRUSortAction.setChecked(EditorList.sortOrder == MRU_SORT);
         windowScopeAction.setChecked(EditorList.listScope == SET_WINDOW_SCOPE);
         pageScopeAction.setChecked(EditorList.listScope == SET_PAGE_SCOPE);
         if (dropDown) {
             tabGroupScopeAction
                     .setChecked(EditorList.listScope == SET_TAB_GROUP_SCOPE);
         } else {
             tabGroupScopeAction.setEnabled(false);
             if (listScope == SET_TAB_GROUP_SCOPE) {
                 pageScopeAction.setChecked(true);
             }
         }
     }

     /**
      * Updates the specified item
      */
     private void updateItem(TableItem item, Adapter editor) {
         int index = fullNameAction.isChecked() ? 1 : 0;
         item.setData(editorListData, editor);
         item.setText(editor.getDisplayText()[index]);

         Image image = editor.getImage();
         if (image != null) {
             item.setImage(image);
         }

         if (!dropDown) {
             editor.editorRef.addPropertyListener(propertyListener);
         }
     }

     /**
      * Sorts the editors
      */
     private void sort() {
         switch (sortOrder) {
         case NAME_SORT:
             Adapter a[] = new Adapter[elements.size()];
             elements.toArray(a);
             Arrays.sort(a);
             elements = Arrays.asList(a);
             break;
         case MRU_SORT:
             // The elements are already in MRU order
 // TODO: Not in MRU if multiple windows open. Within each window
 // group they are in order, but not overall
 break;
         default:
             break;
         }
     }

     /**
      * Adds all editors to elements
      */
     private void updateEditors(IWorkbenchPage[] pages) {
         for (int j = 0; j < pages.length; j++) {
             IEditorReference editors[] = ((WorkbenchPage) pages[j])
                     .getSortedEditors();
             for (int k = editors.length - 1; k >= 0; k--) {
                 elements.add(new Adapter(editors[k]));
             }
         }
     }

     private void getAllEditors(List elements) {
         if (windowScopeAction.isChecked()) {
             IWorkbenchWindow windows[] = window.getWorkbench()
                     .getWorkbenchWindows();
             for (int i = 0; i < windows.length; i++) {
                 updateEditors(windows[i].getPages());
             }
             // TODO: when multiple windows open, loose files from one of the windows
 // When the view is being restored the active window is not included
 // in the collection. Handle this case, get editors from active page
 if (!dropDown && elements.size() == 0) {
                 IWorkbenchPage page = window.getActivePage();
                 if (page != null) {
                     updateEditors(new IWorkbenchPage[] { page });
                 }
             }
         } else {
             IWorkbenchPage page = window.getActivePage();
             if (page != null) {
                 if (pageScopeAction.isChecked()) {
                     updateEditors(new IWorkbenchPage[] { page });
                 } else {
                     EditorPane editors[] = workbook.getEditors();
                     for (int j = 0; j < editors.length; j++) {
                         elements.add(new Adapter(editors[j]
                                 .getEditorReference()));
                     }
                 }
             }
         }
     }

     /**
      * Updates all items in the table
      */
     private void updateItems() {
         setCheckedMenuItems();
         editorsTable.removeAll();
         elements = new ArrayList ();
         getAllEditors(elements);

         sort();

         Object selection = null;
         if (window.getActivePage() != null) {
             selection = window.getActivePage().getActiveEditor();
         }
         for (Iterator iterator = elements.iterator(); iterator.hasNext();) {
             Adapter e = (Adapter) iterator.next();
             TableItem item = new TableItem(editorsTable, SWT.NULL);
             updateItem(item, e);
             if ((selection != null)
                     && (selection == e.editorRef.getPart(false))) {
                 editorsTable.setSelection(new TableItem[] { item });
                 saveAction.setEnabled(e.isDirty());
             }
         }
     }

     private void fillContextMenu(IMenuManager menuMgr) {
         // SortBy SubMenu
 MenuManager sortMenuMgr = new MenuManager(WorkbenchMessages.EditorList_SortBy_text);
         sortMenuMgr.add(nameSortAction);
         sortMenuMgr.add(MRUSortAction);

         // ApplyTo SubMenu
 MenuManager applyToMenuMgr = new MenuManager(WorkbenchMessages.EditorList_ApplyTo_text);
         applyToMenuMgr.add(windowScopeAction);
         applyToMenuMgr.add(pageScopeAction);
         if (dropDown) {
             applyToMenuMgr.add(tabGroupScopeAction);
         }

         // Main menu
 menuMgr.add(saveAction);
         menuMgr.add(closeAction);
         menuMgr.add(new Separator());
         menuMgr.add(selectCleanAction);
         menuMgr.add(InvertSelectionAction);
         menuMgr.add(selectAllAction);
         menuMgr.add(new Separator());
         menuMgr.add(fullNameAction);
         menuMgr.add(sortMenuMgr);
         menuMgr.add(applyToMenuMgr);
     }

     private class SaveAction extends Action {
         /**
          * Create an instance of this class
          */
         private SaveAction() {
             setText(WorkbenchMessages.EditorList_saveSelected_text);
             setToolTipText(WorkbenchMessages.EditorList_saveSelected_toolTip);
             PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
                     IWorkbenchHelpContextIds.SAVE_ACTION);
         }

         /**
          * Performs the save.
          */
         public void run() {
             TableItem[] items = editorsTable.getSelection();
             List dirtyEditorList = new ArrayList ();

             for (int i = 0; i < items.length; i++) {
                 Adapter editor = (Adapter) items[i].getData(editorListData);
                 Object element = editor.editorRef.getPart(false);
                 if (editor.isDirty()) {
                     dirtyEditorList.add(element);
                 }
             }

             if (dirtyEditorList.size() != 0) {
                 EditorManager.saveAll(dirtyEditorList, false, false, window);
             }
             destroyControl();
         }
     }

     /**
      * Closes the selected editor.
      */
     private class CloseAction extends Action {
         /**
          * Create an instance of this class
          */
         private CloseAction() {
             setText(WorkbenchMessages.EditorList_closeSelected_text);
             setToolTipText(WorkbenchMessages.EditorList_closeSelected_toolTip);
             PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
                     IWorkbenchHelpContextIds.CLOSE_PART_ACTION);
         }

         /**
          * Close the selected editor.
          */
         public void run() {
             TableItem[] items = editorsTable.getSelection();
             Adapter[] editorRef = new Adapter[items.length];
             List dirtyEditorList = new ArrayList ();

             // store the editor references as editorsTable will
 // be disposed when focus is lost.
 for (int i = 0; i < items.length; i++) {
                 editorRef[i] = (Adapter) items[i].getData(editorListData);
                 Object element = editorRef[i].editorRef.getPart(false);
                 if (editorRef[i].isDirty()) {
                     dirtyEditorList.add(element);
                 }
             }

             boolean result = true;
             if (dirtyEditorList.size() != 0) {
                 result = EditorManager.saveAll(dirtyEditorList, true, true, window);
             }

             // now close the editors
 if (result) {
                 for (int i = 0; i < editorRef.length; i++) {
                     editorRef[i].close();
                 }
             }

             notifyEditorListViews();
             destroyControl();
         }
     }

     /**
      * Selects editors.
      */
     private class SelectionAction extends Action {
         private int selectionType;

         /**
          * Create an instance of this class
          */
         private SelectionAction(int selectionType) {
             this.selectionType = selectionType;

             switch (selectionType) {
             case SELECT_ALL:
                 setText(WorkbenchMessages.EditorList_selectAll_text);
                 setToolTipText(WorkbenchMessages.EditorList_selectAll_toolTip);
                 break;
             case INVERT_SELECTION:
                 setText(WorkbenchMessages.EditorList_invertSelection_text);
                 setToolTipText(WorkbenchMessages.EditorList_invertSelection_toolTip);
                 break;
             case SELECT_CLEAN:
                 setText(WorkbenchMessages.EditorList_selectClean_text);
                 setToolTipText(WorkbenchMessages.EditorList_selectClean_toolTip);
                 break;
             default:
                 break;
             }
             // WorkbenchHelp.setHelp(this, IHelpContextIds.SELECTION_ACTION);
 }

         private TableItem[] invertSelection(TableItem[] allItems,
                 TableItem[] selectedItems) {
             if (allItems.length == 0) {
                 return allItems;
             }
             ArrayList invertedSelection = new ArrayList (allItems.length
                     - selectedItems.length);
             outerLoop: for (int i = 0; i < allItems.length; i++) {
                 for (int j = 0; j < selectedItems.length; j++) {
                     if (allItems[i] == selectedItems[j]) {
                         continue outerLoop;
                     }
                 }
                 invertedSelection.add(allItems[i]);
             }

             TableItem result[] = new TableItem[invertedSelection.size()];
             invertedSelection.toArray(result);
             return result;
         }

         private TableItem[] selectClean(TableItem[] allItems) {
             if (allItems.length == 0) {
                 return new TableItem[0];
             }
             ArrayList cleanItems = new ArrayList (allItems.length);
             for (int i = 0; i < allItems.length; i++) {
                 Adapter editor = (Adapter) allItems[i].getData(editorListData);
                 if (!editor.isDirty()) {
                     cleanItems.add(allItems[i]);
                 }
             }
             TableItem result[] = new TableItem[cleanItems.size()];
             cleanItems.toArray(result);

             return result;
         }

         /**
          * Select editors.
          */
         public void run() {
             switch (selectionType) {
             case SELECT_ALL:
                 editorsTable.setSelection(editorsTable.getItems());
                 break;
             case INVERT_SELECTION:
                 editorsTable.setSelection(invertSelection(editorsTable
                         .getItems(), editorsTable.getSelection()));
                 break;
             case SELECT_CLEAN:
                 editorsTable.setSelection(selectClean(editorsTable.getItems()));
                 break;
             }
             handleSelectionEvent(false);
         }
     }

     /**
      * Displays the full file name.
      */
     private class FullNameAction extends Action {
         /**
          * Create an instance of this class
          */
         private FullNameAction() {
             setText(WorkbenchMessages.EditorList_FullName_text);
             setToolTipText(WorkbenchMessages.EditorList_FullName_toolTip);
        
         }

         /**
          * Display full file name.
          */
         public void run() {
             displayFullPath = !displayFullPath;
             WorkbenchPlugin.getDefault().getPreferenceStore().setValue(
                     IPreferenceConstants.EDITORLIST_DISPLAY_FULL_NAME,
                     displayFullPath);
             setChecked(displayFullPath);
             int[] indices = editorsTable.getSelectionIndices();
             updateItems();
             if (dropDown) {
                 //TODO commented out for presentation work
 //workbook.resizeEditorList();
 }
             editorsTable.setSelection(indices);
             notifyEditorListViews();
         }
     }

     private class SortAction extends Action {
         private int sortOrder;

         /**
          * Create an instance of this class
          */
         private SortAction(int sortOrder) {
             this.sortOrder = sortOrder;
             switch (sortOrder) {
             case NAME_SORT:
                 setText(WorkbenchMessages.EditorList_SortByName_text);
                 setToolTipText(WorkbenchMessages.EditorList_SortByName_toolTip);
                 break;
             case MRU_SORT:
                 setText(WorkbenchMessages.EditorList_SortByMostRecentlyUsed_text);
                 setToolTipText(WorkbenchMessages.EditorList_SortByMostRecentlyUsed_toolTip);
                 break;
             default:
                 break;
             }
             // WorkbenchHelp.setHelp(this, IHelpContextIds.SORT_ACTION);
 }

         /**
          * Performs the sort.
          */
         public void run() {
             EditorList.sortOrder = this.sortOrder;
             WorkbenchPlugin.getDefault().getPreferenceStore().setValue(
                     IPreferenceConstants.EDITORLIST_SORT_CRITERIA,
                     this.sortOrder);
             TableItem[] items = editorsTable.getItems();
             if (items.length == 0) {
                 return;
             }
             updateItems();
             notifyEditorListViews();
         }
     }

     private class SetScopeAction extends Action {
         private int whichScope;

         /**
          * Create an instance of this class
          */
         private SetScopeAction(int whichScope) {
             this.whichScope = whichScope;
             switch (whichScope) {
             case SET_WINDOW_SCOPE:
                 setText(WorkbenchMessages.EditorList_DisplayAllWindows_text);
                 setToolTipText(WorkbenchMessages.EditorList_DisplayAllWindows_toolTip);
                 break;
             case SET_PAGE_SCOPE:
                 setText(WorkbenchMessages.EditorList_DisplayAllPage_text);
                 setToolTipText(WorkbenchMessages.EditorList_DisplayAllPage_toolTip);
                 break;
             case SET_TAB_GROUP_SCOPE:
                 setText(WorkbenchMessages.EditorList_DisplayTabGroup_text);
                 setToolTipText(WorkbenchMessages.EditorList_DisplayTabGroup_toolTip);
                 break;
             default:
                 break;
             }
             // WorkbenchHelp.setHelp(this, IHelpContextIds.SORT_EDITOR_SCOPE_ACTION);
 }

         /**
          * Display the appropriate scope.
          */
         public void run() {
             EditorList.listScope = this.whichScope;
             WorkbenchPlugin.getDefault().getPreferenceStore().setValue(
                     IPreferenceConstants.EDITORLIST_SELECTION_SCOPE,
                     this.whichScope);
             updateItems();
             if (dropDown) {
                 //TODO commented out for presentation work
 //workbook.resizeEditorList();
 }
             notifyEditorListViews();
         }
     }

     /**
      * A helper inner class
      */
     private class Adapter implements Comparable {
         IEditorReference editorRef;

         String text[], displayText[];

         Image images[];

         Adapter(IEditorReference ref) {
             editorRef = ref;
         }

         boolean isDirty() {
             return editorRef.isDirty();
         }

         void close() {
             WorkbenchPage p = ((WorkbenchPartReference) editorRef).getPane()
                     .getPage();
             p.closeEditor(editorRef, false);
         }

         // file name without any dirty indication, used for sorting
 String [] getText() {
             text = new String [2];
             text[0] = editorRef.getTitle();
             text[1] = editorRef.getTitleToolTip();
             return text;
         }

         // file name with dirty indication, used for displaying
 String [] getDisplayText() {
             displayText = new String [2];

             if (editorRef.isDirty()) {
                 displayText[0] = "*" + editorRef.getTitle(); //$NON-NLS-1$
 displayText[1] = "*" + editorRef.getTitleToolTip(); //$NON-NLS-1$
 } else {
                 displayText[0] = editorRef.getTitle();
                 displayText[1] = editorRef.getTitleToolTip();
             }
             return displayText;
         }

         Image getImage() {
             return editorRef.getTitleImage();
         }

         private void activate(boolean activate) {
             IEditorPart editor = editorRef.getEditor(true);
             if (editor != null) {
                 WorkbenchPage p = (WorkbenchPage) editor.getEditorSite()
                         .getPage();
                 Shell s = p.getWorkbenchWindow().getShell();
                 if (s.getMinimized()) {
                     s.setMinimized(false);
                 }
                 s.moveAbove(null);
                 p.getWorkbenchWindow().setActivePage(p);
                 if (activate) {
                     if (editor == p.getActivePart()) {
                         editor.setFocus();
                     } else {
                         p.activate(editor);
                     }
                 } else {
                     p.bringToTop(editor);
                 }
             }
         }

         public int compareTo(Object another) {
             int index = fullNameAction.isChecked() ? 1 : 0;
             Adapter adapter = (Adapter) another;
             int result = collator.compare(getText()[index],
                     adapter.getText()[index]);
             return result;
         }
     }
 }

